#include "netdisk.h"

// 实现 cd 命令，用于切换当前工作目录
// const char* arg：指向要切换到代码剥的路径字符串
// start_t *dir：指向栈结构的指针，栈中存储当前的工作目录路径
int cdFunc(const char* arg, Stack_t* dir)
{

    char path[4096]; // 用于存储完整的路径
    // 调用 onePath 函数，根据arg 和当前的栈dir 构建完整的路径,path是拼接后的路径
    onePath(arg,path,dir); 
    printf("path_cd = %s\n", path);// 打印

    // 使用access函数检查路径是否存在，F_OK表示检查路径是否存在
    if (access(path, F_OK) == -1) {
        perror("access"); // 若不存在则打印错误信息，并返回 -1 
        return -1;
    }

    char argv[4096]; // 存储用户输入的路径参数的副本，方便后续处理
    strcpy(argv,arg);// 将一个字符串复制到另一个字符串中！！！
    // printf("cd_onepath=%s\n",path);

    // ------------------------------------处理绝对路径-----------------------------------
    if (arg[0] == '/') {  // 如果用户输入的路径以‘/’开头，则表示这是一个绝对路径
        // 如果栈中有多于一个元素（即用户不存在根目录），则弹出除根目录外的所有元素
        // 这是因为绝对路径会覆盖当前路径，从根目录开始重新构建路径
        for (int i = 0; i < dir->stackSize - 1; i++) {// 注意：-1是因为根目录 / 不会被弹出
            char str[256];
            pop(dir, str);
        }
        // 遍历栈
        travel_stack(*dir,argv);// argv = /
        // printf("argv = %s\n",argv);

        // 按照 / 分割路径path
        char* p;
        strtok(path, "/"); // 取命令
        strtok(NULL, "/"); // 路径
        // 将取出的路径组件压入到栈 dir 中
        while ((p = strtok(NULL, "/")) != NULL) {
            push(dir, p);
        }

        // 用户输入的路径以 .. 开头，表示需要切换到上一级目录
    } else if (arg[0] == '.' && arg[1] == '.') {
        // 若栈 dir 的大小为1，说明以及到达跟目录，无法再向上切换，直接返回 0
        if (dir->stackSize == 1) {// 此时栈中只有根目录‘/’
            return 0;
        }
        char str[256] = {0};
        // 从栈dir中弹出一个元素（即当前目录）,并将其存储在str中
        // 这模拟了用户离开当前目录，返回到上一级目录的操作
        pop(dir, str);
        char* p;

        // 使用 strtok 函数按/分割用户输入的路径argv
        if ((p = strtok(argv, "/")) == NULL){
            // 表示用户输入的路径为空或不包括任何 / 分割的目录名，直接返回
            // printf("argv = %s\n",argv);
            return 0;

        }

        // 若用户输入的目录名包括其它目录名（如../bin），逐个将路径组件压入到栈dir
        while ((p = strtok(NULL, "/")) != NULL) {
            // printf("p = %s\n",p);
            push(dir, p);
        }

        // 处理当前目录或相对路径
    } else {
        // 若用户输入的路径不是以/或者..开头，可能是普通相对路径或当前目录（.）
        // 若路径是.或空字符串，直接返回0
        if (arg[0] == '.' && arg[1] == '\0' || arg[0] == '\0'){
            return 0;
        }

        // 使用strtok函数按/分割用户输入的路径argv，将每个部分进行入栈
        char* p;
        p=strtok(argv,"/");
        if(p == NULL){
            return 0;
        }
        // 并逐个将路径组件压入栈dir
        if(p[0]!='.')
        push(dir,p);
        while ((p = strtok(NULL, "/")) != NULL) {
            push(dir, p);
        }
    }
}
